Function.RegisterNamespace("System.IO");

System.IO.Path=new function(){
    var _driveMarker=":";
    var _protocolMarker="://";
    var _root;
    var _webSeparator="/";

    this.DirectorySeparator=_webSeparator;
    
    this.Combine=function(path1,path2){
        if(path1==undefined||!Object.IsType(Function,path1.toString))throw new Error("System.IO.Path.Combine: 'path1' must be convertible to String.");
        if(path2==undefined||!Object.IsType(Function,path2.toString))throw new Error("System.IO.Path.Combine: 'path2' must be convertible to String.");
        path1=this.Normalize(path1);
        path2=this.Normalize(path2);
        if(String.EndsWith(path1,this.DirectorySeparator))path1=path1.slice(0,-1);
        if(String.StartsWith(path2,this.DirectorySeparator))path2=path2.slice(1);
        return [path1,path2].join(path1&&path2&&this.DirectorySeparator||'');
    };
    
    this.GetFileName=function(path){
        if(path==undefined||!Object.IsType(Function,path.toString))throw new Error("System.IO.Path.GetFileName: 'path' must be convertible to String.");
        path=this.Normalize(path);
        return path.substring(path.lastIndexOf(this.DirectorySeparator)+1,path.length);
    };
    
    this.GetFullPath=function(path){
        if(path==undefined||!Object.IsType(Function,path.toString))throw new Error("System.IO.Path.GetFullPath: 'path' must be convertible to String.");
        var pathHasProtocol=String.Contains(path,_protocolMarker);
        path=this.Normalize(path,pathHasProtocol&&_webSeparator);
        var root=this.GetRoot();
        var rootHasProtocol=String.Contains(root,_protocolMarker);
        if(rootHasProtocol)root=this.Normalize(root,_webSeparator);
        if(String.Contains(root,_driveMarker)||rootHasProtocol||String.StartsWith(root,this.DirectorySeparator)||!String.StartsWith(path,root)){
            if(!String.Contains(path,_driveMarker)&&!pathHasProtocol&&!String.StartsWith(path,this.DirectorySeparator)){
                return this.Combine(root,path);
            }
        }
        return path;
    };
    
    this.GetPath=function(path){
        if(path==undefined||!Object.IsType(Function,path.toString))throw new Error("System.IO.Path.GetPath: 'path' must be convertible to String.");
        path=this.Normalize(path);
        if(path.lastIndexOf(this.DirectorySeparator)>-1)return path.substr(0,path.lastIndexOf(this.DirectorySeparator));
        return path;
    };
        
    this.GetRoot=function(){
        return _root||'';
    };

    this.Normalize=function(path,separator){
        if(path==undefined||!Object.IsType(Function,path.toString))throw new Error("System.IO.Path.Normalize: 'path' must be convertible to String.");
        return path.toString().replace(/[\\\/]/gm,separator||this.DirectorySeparator);
    };

    this.SetRoot=function(path){
        if(path==undefined||!Object.IsType(Function,path.toString))throw new Error("System.IO.Path.SetRoot: 'path' must be convertible to String.");
        path=this.Normalize(path);
        var separator=this.DirectorySeparator;
        if(path.indexOf(separator)>-1){
            var parts=path.split(separator);
            var last=parts[parts.length-1];
            if(!last||(last.indexOf('.')>-1&&!System.IO.Directory.Exists(path)))parts.length--;
            _root=parts.join(separator)+separator;
        }else _root=path+separator;
    };
};